package com.shuqi.database.dao.impl;

import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.j256.ormlite.dao.RuntimeExceptionDao;
import com.j256.ormlite.stmt.DeleteBuilder;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.UpdateBuilder;
import com.j256.ormlite.stmt.Where;
import com.shuqi.application.CataLogCache;
import com.shuqi.application.ShuqiApplication;
import com.shuqi.common.utils.Log4an;
import com.shuqi.database.dao.OrmBaseDao;
import com.shuqi.database.model.BookCataLog;

/**
 * 书籍目录操作逻辑
 * 
 * @author hxp
 * @date 2014-3-9
 * 
 */
public class BookCataLogDao extends OrmBaseDao {

    private static BookCataLogDao mInstance;

    private RuntimeExceptionDao<BookCataLog, Integer> mDao = ShuqiDatabaseHelper.getHelper(
            ShuqiApplication.getContext()).getRuntimeExceptionDao(BookCataLog.class);

    private BookCataLogDao(Context context) {

    }

    public static synchronized BookCataLogDao getInstance() {
        if (mInstance == null) {
            mInstance = new BookCataLogDao(ShuqiApplication.getContext());
        }
        return mInstance;
    }

    /**
     * 
     * 按页获取当前书 当前卷 的目录信息
     * 
     * @param bookId 书籍ID
     * @param sourceId 书籍来源ID
     * @param uid 当前用户ID
     * @param vid 卷ID
     * @param pageIndex 页索引
     * @param pageSize 页大小
     * @return
     */
    public List<BookCataLog> getCatalogByPageIndex(String bookId, String sourceId, String uid,
            String vid, int pageIndex, int pageSize) {
        List<BookCataLog> resultList = null;
        QueryBuilder<BookCataLog, Integer> queryBuilder = mDao.queryBuilder();
        try {
            Where<BookCataLog, Integer> where = queryBuilder.where();
            where.eq("book_id", bookId);
            if (TextUtils.isEmpty(sourceId)) {
                sourceId = "";
            }
            where.and().eq("source_id", sourceId);
            where.and().eq("volume_id", vid);
            where.and().eq("user_id", uid);
            queryBuilder.limit(Long.valueOf(pageSize));
            queryBuilder.offset(Long.valueOf(pageSize * (pageIndex - 1)));
            resultList = queryBuilder.query();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return resultList;
    }

    /**
     * 
     * 插入或更新书籍目录信息
     * 
     * @param uid 当前用户ID
     * @param bookId 书籍ID
     * @param sourceId 书籍来源ID
     * @param catalogList 书籍目录信息
     */
    public void saveOrUpdateCatalog(final String uid, final String bookId, final String sourceId,
            final List<BookCataLog> catalogList) {
        try {
            openTransactionManager(ShuqiDatabaseHelper.getHelper(ShuqiApplication.getContext()),
                    new Callable<Void>() {
                        @Override
                        public Void call() throws Exception {
                            // 读出老的目录数据 *******************************
                            QueryBuilder<BookCataLog, Integer> queryBuilder = mDao.queryBuilder();
                            List<BookCataLog> oldCataLog = null;
                            try {
                                Where<BookCataLog, Integer> where = queryBuilder.where();
                                where.eq("book_id", bookId);
                                where.and().eq(
                                        "source_id",
                                        TextUtils.isEmpty(sourceId) || "null".equals(sourceId) ? ""
                                                : sourceId);
                                where.and().eq("user_id", uid);
                                queryBuilder.selectColumns("chapter_id", "download_state");
                                // 只获取章节id和下载状态
                                oldCataLog = queryBuilder.query();
                            } catch (SQLException e) {
                                e.printStackTrace();
                            }
                            // 组装数据到 map<cid,oldcatalog>
                            Map<String, Integer> map = null;
                            if (oldCataLog != null && oldCataLog.size() > 0) {
                                map = new HashMap<String, Integer>();
                                for (BookCataLog bookCataLog : oldCataLog) {
                                    map.put(bookCataLog.getChapterId(),
                                            bookCataLog.getDownloadState());
                                }
                            }
                            oldCataLog.clear();
                            oldCataLog = null;
                            // 读出老的目录数据 *******************************

                            /** 删除数据库中该书的目录 */
                            DeleteBuilder<BookCataLog, Integer> deleteBuilder =
                                    mDao.deleteBuilder();
                            Where<BookCataLog, Integer> where = deleteBuilder.where();
                            where.eq("book_id", bookId);
                            if (TextUtils.isEmpty(sourceId)) {
                                where.and().eq("source_id", "");
                            } else {
                                where.and().eq("source_id", sourceId);
                            }
                            where.and().eq("user_id", uid);
                            deleteBuilder.delete();

                            boolean hasOldData = map != null && map.size() > 0;

                            /** 插入该书的新目录 */
                            for (BookCataLog catalog : catalogList) {
                                if (TextUtils.isEmpty(catalog.getSourceId())) {
                                    catalog.setSourceId("");
                                }
                                // 存储删除之前的下载状态
                                if (hasOldData
                                        && BookCataLog.HAS_DOWN == map.get(catalog.getChapterId())) {
                                    catalog.setDownloadState(BookCataLog.HAS_DOWN);
                                    Log.e("mine",
                                            "save has download cid = " + catalog.getChapterId());
                                }
                                mDao.create(catalog);
                            }
                            notifyChanger(bookId, sourceId, uid);
                            return null;
                        }
                    });
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * 更新单条目录信息
     * 
     * @param catalog
     */
    // public void updateCatalog(BookCataLog catalog) {
    // UpdateBuilder<BookCataLog, Integer> updateBuilder = mDao.updateBuilder();
    // try {
    // Where<BookCataLog, Integer> where = updateBuilder.where();
    // where.eq("book_id", catalog.getBookId());
    // if(TextUtils.isEmpty(catalog.getSourceId())){
    // catalog.setSourceId("");
    // }
    // where.and().eq("source_id", catalog.getSourceId());
    // where.and().eq("user_id", catalog.getUserId());
    //
    // /** 设置更新的列信息 */
    // updateBuilder.updateColumnValue("pay_state", catalog.getPayState());
    //
    // updateBuilder.update();
    // } catch (SQLException e) {
    // e.printStackTrace();
    // }
    // }

    /**
     * 
     * 更新某本书的某章节为购买状态
     * 
     * @param bookId
     * @param sourceId
     * @param uid
     */
    public void updateCatalogAllToPaid(String bookId, String uid) {
        UpdateBuilder<BookCataLog, Integer> updateBuilder = mDao.updateBuilder();
        try {
            Where<BookCataLog, Integer> where = updateBuilder.where();
            where.eq("book_id", bookId);
            where.and().eq("user_id", uid);
            where.and().eq("source_id", "");

            /** 设置为已经购买 */
            updateBuilder.updateColumnValue("pay_state", BookCataLog.HAS_PAY);
            updateBuilder.update();
            notifyChanger(bookId, "", uid);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * 更新某本书的某章节为购买状态
     * 
     * @param bookId
     * @param sourceId
     * @param uid
     */
    public void updateCatalogToPaid(String bookId, String sourceId, String uid, String chapterId) {
        UpdateBuilder<BookCataLog, Integer> updateBuilder = mDao.updateBuilder();
        try {
            Where<BookCataLog, Integer> where = updateBuilder.where();
            where.eq("book_id", bookId);
            where.and().eq("user_id", uid);
            if (sourceId == null) {
                sourceId = "";
            }
            where.and().eq("source_id", sourceId);
            where.and().eq("chapter_id", chapterId);

            /** 设置为已经购买 */
            updateBuilder.updateColumnValue("pay_state", BookCataLog.HAS_PAY);
            updateBuilder.update();
            notifyChanger(bookId, sourceId, uid);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * 更新某本书的某章节为已下载
     * 
     * @param bookId
     * @param sourceId
     * @param uid
     */
    public void updateCatalogToDown(String bookId, String sourceId, String uid, String chapterId) {
        UpdateBuilder<BookCataLog, Integer> updateBuilder = mDao.updateBuilder();
        try {
            Where<BookCataLog, Integer> where = updateBuilder.where();
            where.eq("book_id", bookId);
            where.and().eq("user_id", uid);
            if (sourceId == null) {
                sourceId = "";
            }
            where.and().eq("source_id", sourceId);
            where.and().eq("chapter_id", chapterId);

            /** 设置为已经购买 */
            updateBuilder.updateColumnValue("download_state", BookCataLog.HAS_DOWN);
            updateBuilder.update();
            notifyChanger(bookId, sourceId, uid);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * 批量更新某本书的某些章节为已下载
     * 
     * @param bookId
     * @param sourceId
     * @param uid
     */
    public void attachUpdateCatalogToDown(String bookId, String uid, String[] chapters) {
        if (chapters == null || chapters.length <= 0) {
            return;
        }
        UpdateBuilder<BookCataLog, Integer> updateBuilder = mDao.updateBuilder();
        try {
            Where<BookCataLog, Integer> where = updateBuilder.where();
            where.eq("book_id", bookId);
            where.and().eq("user_id", uid);
            where.and().eq("source_id", "");
            List<String> chaptersList = Arrays.asList(chapters);
            if (chaptersList != null) {
                where.and().in("chapter_id", chaptersList);
            }
            /** 设置为已经购买 */
            updateBuilder.updateColumnValue("download_state", BookCataLog.HAS_DOWN);
            updateBuilder.update();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    /**
     * 
     * 根据章节ID获取某本书的某一章节目录信息
     * 
     * @param uid
     * @param bookId
     * @param sourceId
     * @param chapterid
     * @return
     */
    public BookCataLog getBookCatalogByCid(String uid, String bookId, String sourceId,
            String chapterid) {
        if (TextUtils.isEmpty(chapterid)) {
            return null;
        }
        BookCataLog cataLog =
                CataLogCache.getInstance().getBookCatalogByCid(uid, bookId, sourceId, chapterid);
        if (cataLog != null) {
            return cataLog;
        }

        QueryBuilder<BookCataLog, Integer> queryBuilder = mDao.queryBuilder();
        List<BookCataLog> bookCataLog = null;
        try {
            Where<BookCataLog, Integer> where = queryBuilder.where();
            where.eq("book_id", bookId);
            if (TextUtils.isEmpty(sourceId)) {
                sourceId = "";
            }
            where.and().eq("source_id", sourceId);
            where.and().eq("user_id", uid);
            where.and().eq("chapter_id", chapterid);

            bookCataLog = queryBuilder.query();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if (bookCataLog != null && bookCataLog.size() > 0) {
            return bookCataLog.get(0);
        } else {
            return null;
        }
    }

    /**
     * 
     * 根据章节索引获取某本书的某一章目录信息
     * 
     * @param uid
     * @param bookId
     * @param sourceId
     * @param index
     * @return
     */
    public BookCataLog getBookCatalogByChapterIndex(String uid, String bookId, String sourceId,
            int index) {
        if (index == 0) {
            index = 1;
        }
        QueryBuilder<BookCataLog, Integer> queryBuilder = mDao.queryBuilder();
        List<BookCataLog> bookCataLog = null;
        try {
            Where<BookCataLog, Integer> where = queryBuilder.where();
            where.eq("book_id", bookId);
            if (TextUtils.isEmpty(sourceId)) {
                sourceId = "";
            }
            where.and().eq("source_id", sourceId);
            where.and().eq("user_id", uid);
            where.and().eq("chapter_state", BookCataLog.IS_CHATPTER);
            queryBuilder.orderBy("_id", true);
            queryBuilder.limit(Long.valueOf(1));
            queryBuilder.offset(Long.valueOf(index - 1));
            bookCataLog = queryBuilder.query();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if (bookCataLog != null && bookCataLog.size() > 0) {
            return bookCataLog.get(0);
        } else {
            return null;
        }
    }

    /**
     * 根据索引ID获取ID之后的pageSize条数据
     * 
     * @param uid
     * @param bookId
     * @param sourceId
     * @param index
     * @param pageSize
     * @return
     */
    public List<BookCataLog> getBookCatalogListFromChapterIndex(String uid, String bookId,
            String sourceId, int index, int pageSize) {
        List<BookCataLog> result =
                CataLogCache.getInstance().getBookCatalogListFromChapterIndex(uid, bookId,
                        sourceId, index, pageSize);
        if (result != null) {
            return result;
        }
        QueryBuilder<BookCataLog, Integer> queryBuilder = mDao.queryBuilder();
        List<BookCataLog> bookCataLog = null;
        try {
            Where<BookCataLog, Integer> where = queryBuilder.where();
            where.eq("book_id", bookId);
            if (TextUtils.isEmpty(sourceId)) {
                sourceId = "";
            }
            where.and().eq("source_id", sourceId);
            where.and().eq("user_id", uid);
            where.and().ge("oid", index);
            queryBuilder.orderBy("_id", true);
            queryBuilder.limit(Long.valueOf(pageSize));
            bookCataLog = queryBuilder.query();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if (bookCataLog != null && bookCataLog.size() > 0) {
            return bookCataLog;
        } else {
            return null;
        }
    }



    /**
     * 
     * 获取某本书的全部目录信息
     * 
     * @param uid
     * @param bookId
     * @param sourceId
     * @return
     */
    public List<BookCataLog> getAllCatalog(String uid, String bookId, String sourceId) {
        QueryBuilder<BookCataLog, Integer> queryBuilder = mDao.queryBuilder();
        List<BookCataLog> bookCataLog = null;
        try {
            Where<BookCataLog, Integer> where = queryBuilder.where();
            where.eq("book_id", bookId);
            if (TextUtils.isEmpty(sourceId)) {
                sourceId = "";
            }
            where.and().eq("source_id", sourceId);
            where.and().eq("user_id", uid);
            queryBuilder.orderBy("_id", true);
            bookCataLog = queryBuilder.query();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return bookCataLog;
    }

    /**
     * 
     * 获取某本书的全部章节目录信息
     * 
     * @param uid
     * @param bookId
     * @param sourceId
     * @return
     */
    public List<BookCataLog> getAllChapterCatalog(String uid, String bookId, String sourceId) {
        QueryBuilder<BookCataLog, Integer> queryBuilder = mDao.queryBuilder();
        List<BookCataLog> bookCataLog = null;
        try {
            Where<BookCataLog, Integer> where = queryBuilder.where();
            where.eq("book_id", bookId);
            if (TextUtils.isEmpty(sourceId)) {
                sourceId = "";
            }
            where.and().eq("source_id", sourceId);
            where.and().eq("chapter_state", BookCataLog.IS_CHATPTER);
            where.and().eq("user_id", uid);
            queryBuilder.orderBy("_id", true);
            bookCataLog = queryBuilder.query();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return bookCataLog;
    }

    /**
     * 
     * 获取某本书的章节总数
     * 
     * @param uid
     * @param bookId
     * @param sourceId
     * @return
     */
    public long getChapterCount(String uid, String bookId, String sourceId) {
        QueryBuilder<BookCataLog, Integer> queryBuilder = mDao.queryBuilder();
        long count = 0;
        try {
            Where<BookCataLog, Integer> where = queryBuilder.where();
            where.eq("book_id", bookId);
            if (TextUtils.isEmpty(sourceId)) {
                sourceId = "";
            }
            where.and().eq("source_id", sourceId);
            where.and().eq("user_id", uid);
            where.and().eq("chapter_state", BookCataLog.IS_CHATPTER);
            count = queryBuilder.countOf();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 该书籍是否已经下载了目录
     * 
     * @param uid
     * @param bookId
     * @param sourceId
     * @return
     */
    public long isDownLoadShuqiBookCatalog(String uid, String bookId) {
        QueryBuilder<BookCataLog, Integer> queryBuilder = mDao.queryBuilder();
        long count = 0;
        try {
            Where<BookCataLog, Integer> where = queryBuilder.where();
            where.eq("book_id", bookId);
            where.and().eq("source_id", "");
            where.and().eq("user_id", uid);
            where.and().eq("chapter_state", BookCataLog.IS_CHATPTER);
            return queryBuilder.countOf();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 下载完毕后：更新某本书为已下载状态
     * 
     * @param bookId
     * @param uid
     */
    public int updateAllCatalogToDown(String bookId, String uid) {
        int num = -1;
        UpdateBuilder<BookCataLog, Integer> updateBuilder = mDao.updateBuilder();
        try {
            Where<BookCataLog, Integer> where = updateBuilder.where();
            where.eq("book_id", bookId);
            where.and().eq("user_id", uid);
            where.and().eq("source_id", "");
            where.and().eq("chapter_state", BookCataLog.IS_CHATPTER);
            updateBuilder.updateColumnValue("download_state", BookCataLog.HAS_DOWN);
            num = updateBuilder.update();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        Log4an.i("BookCatalogDao", "updateAllCatalogToDown() bookId=" + bookId + " uid=" + uid
                + " num = " + num);
        return num;
    }

    /**
     * 
     * 获取某本书已下载的数量
     * 
     * @param uid
     * @param bookId
     * @param sourceId
     * @return
     */
    public long getChapterDownLoadCount(String uid, String bookId) {
        QueryBuilder<BookCataLog, Integer> queryBuilder = mDao.queryBuilder();
        long count = 0;
        try {
            Where<BookCataLog, Integer> where = queryBuilder.where();
            where.eq("book_id", bookId);
            where.and().eq("source_id", "");
            where.and().eq("user_id", uid);
            where.and().eq("download_state", BookCataLog.HAS_DOWN);
            count = queryBuilder.countOf();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 
     * 获取某卷下所有章节的数量
     * 
     * @param uid
     * @param bookId
     * @param sourceId
     * @param vid
     * @return
     */
    public long getChapterCountOfVolume(String uid, String bookId, String sourceId, String vid) {
        QueryBuilder<BookCataLog, Integer> queryBuilder = mDao.queryBuilder();
        long count = 0;
        try {
            Where<BookCataLog, Integer> where = queryBuilder.where();
            where.eq("book_id", bookId);
            if (TextUtils.isEmpty(sourceId)) {
                sourceId = "";
            }
            where.and().eq("source_id", sourceId);
            where.and().eq("user_id", uid);
            where.and().eq("volume_id", vid);
            count = queryBuilder.countOf();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 获取cidSet 中需要下载的chapterID set
     * 
     * @param uid
     * @param bookId
     * @param cidSet
     * @return
     */
    public HashSet<String> getNeedDownLoadCidSet(String uid, String sourceId, String bookId,
            HashSet<String> cidSet) {
        if (cidSet == null || cidSet.size() <= 0) {
            return null;
        }
        HashSet<String> result =
                CataLogCache.getInstance().getNeedDownLoadCidSet(uid, sourceId, bookId, cidSet);
        if (result != null) {
            return result;
        }
        QueryBuilder<BookCataLog, Integer> queryBuilder = mDao.queryBuilder();
        try {
            Where<BookCataLog, Integer> where = queryBuilder.where();
            where.eq("book_id", bookId);
            where.and().eq("user_id", uid);
            if (sourceId == null) {
                where.and().eq("source_id", "");
            } else {
                where.and().eq("source_id", sourceId);
            }
            where.and().eq("download_state", BookCataLog.UN_DOWN);
            where.and().in("chapter_id", cidSet);
            List<BookCataLog> list = queryBuilder.query();
            if (list != null && list.size() > 0) {
                HashSet<String> chapterSet = new HashSet<String>();
                for (BookCataLog catalog : list) {
                    chapterSet.add(catalog.getChapterId());
                }
                return chapterSet;
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     * 根据BookId sourceId 删除书籍目录
     * 
     * @param bookId
     * @param sourceId
     * @param userId
     */
    public int deleteBookCatalogByBookId(String bookId, String sourceId, String userId) {
        DeleteBuilder<BookCataLog, Integer> deleteBuilder = mDao.deleteBuilder();
        Where<BookCataLog, Integer> where = deleteBuilder.where();
        try {
            where.eq("book_id", bookId);
            if (sourceId == null) {
                where.and().eq("source_id", "");
            } else {
                where.and().eq("source_id", sourceId);
            }
            where.and().eq("user_id", userId);
            return deleteBuilder.delete();
        } catch (Exception e) {

        }
        return -1;
    }


    /** 目录页监听数据变化 */
    private CatalogChangerListener mCatalogChangerListener;
    private CatalogChangerActivityListener mCatalogChangerActivityListener;

    public interface CatalogChangerListener {
        void onCatalogChanger(String bookId, String sourceId, String uid);
    }

    public interface CatalogChangerActivityListener {
        void onCatalogChanger();
    }

    public void registerCataLogListener(CatalogChangerListener listener) {
        mCatalogChangerListener = listener;
    }

    public void registerCatalogActivity(CatalogChangerActivityListener listener) {
        mCatalogChangerActivityListener = listener;
    }

    public void unRegisterCataLogListener() {
        mCatalogChangerListener = null;
    }

    private void notifyChanger(String bookId, String sourceId, String uid) {
        if (mCatalogChangerListener != null) {
            mCatalogChangerListener.onCatalogChanger(bookId, sourceId, uid);
        }
        if (mCatalogChangerActivityListener != null) {
            mCatalogChangerActivityListener.onCatalogChanger();
        }
    }
}
